'''
bibao
'''
from builtins import range
def count():
    fs =  []
    for i in range(1,4):
        def f():
            return i * i
        fs.append(f)
    return fs

f1,f2,f3 = count()

print("f1()：",f1())
print("f2()：",f2())
print("f3()：",f3())

#返回闭包时需注意：

'''
返回函数不要引用任何循环变量，或者后续会发生变化的变量


#############
如果一定要引用循环变量怎么办？方法是再创建一个函数，用该函数的参数绑定循环变量当前的值，无论该循环变量后续如何更改，已绑定到函数参数的值不变：
#############


'''
#以上代码修改如下：
def count2():
    fs = []
    def g(i):
        def pow2():
            return i * i
        return pow2
    for i in range(1,4):
        fs.append(g(i))
    return fs
f1,f2,f3 = count2()

print("f1()：",f1())
print("f2()：",f2())
print("f3()：",f3())


#利用闭包返回计数器函数，每次调用返回递增的整数
def createCounter():
    l = [0]
    def counter():
        i = l[-1]
        l.append(i + 1)
        return l[-1]
    return counter

# 测试:
counterA = createCounter()
print(counterA(), counterA(), counterA(), counterA(), counterA()) # 1 2 3 4 5
counterB = createCounter()
if [counterB(), counterB(), counterB(), counterB()] == [1, 2, 3, 4]:
    print('测试通过!')
else:
    print('测试失败!')
    
    
#匿名函数
def is_odd(n):
    return n % 2 == 0
l = list(filter(is_odd,range(1,21)))
print("1-20之间的偶数：",l)

'''匿名函数改造
'''
f  = lambda n : n % 2 == 0
l = list(filter(is_odd,range(1,21)))
print("1-20之间的偶数(匿名函数使用)：",l)



#装饰器
def log(func):
    def f(*args,**kw):
        print("diayiong调用函数",func.__name__)
        return func(*args,**kw)
    return f
@log
def now():
    print("hhhh")
    
now()

#decorator本身传入参数，编写一个返回decorator的高阶函数
def log2(text):
    def decorator(func):
        def wrapper(*args,**kw):
            print('%s %s'%(text,func.__name__))
            return func(*args,**kw)
        return wrapper
    return decorator
@log2('execute')
def now2():
    print("hhhhhhhhhhhh------->>>>>")
now2()
    